import { PhaseEnum } from "@/core/playersystem/phase";
import { Sha, ShaWrapper } from "../basicCard";
import { Card, CardProxy, Color, Equipment, HurtType } from "../card";
import { CardUsingEventHandler, CardUsingEventWrapper, EmptyCardUsingEventHandler } from "@/core/playersystem/handlers";
import { Player } from "@/core/playersystem/player";
import { createDefaultEvent } from "@/store/reactiveStore";
import { Shield } from "./shields";
import { MinusOneHourse, PlusOneHourse } from "./horses";
import { PickPurpose } from "@/core/strategies/BaseSmartBehavior";

const DefaultPromise = <T>(t:T) => new Promise<T>((resolve) => resolve(t));

export class Weapons extends Equipment {

    static areaIndex():number {
        return 0
    }

    /**
     * 处理攻击距离公共逻辑
     * @returns 
     */
    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.equipmentAreas.attackDistances = Math.max(this.cardProperties.owner.equipmentAreas.attackDistances, this.attackDistance())
        }
        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.equipmentAreas.attackDistances = 1
        }
        super.onDrop()
    }

    attackDistance():number {
        return 1
    }

}

/**
 * 雌雄双股剑 TODO 性别机制未实现 待完成
 */
export class CiXiongShuangGuJian extends Weapons {

    cixiongshaProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)

        const cixiongshaProxy: CardProxy<Sha> = {
            name: 'cixiongshaProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const cixiongshaCard = new CiXiongShuangGuJianSha(card)
                return cixiongshaCard
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }

        class CiXiongShuangGuJianSha extends ShaWrapper {

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class CiXiongShaEvent extends CardUsingEventWrapper<Sha> {
                    specTarget() {
                        const player = this.player
                        const target = this.cardUsingEventHandler.card.cardProperties.target
                        if (target && player) {
                            const gm = player.gameManager
                            gm.appendLog('雌雄双股剑 TODO作用生效在此处实现中...')
                        }
                        return super.specTarget()
                    }
                }
                return new CiXiongShaEvent(res)
            }

            info(): string {
                return "雌雄双股剑" + this.sourceCard.info()
            }
        }

        this.cixiongshaProxy = cixiongshaProxy
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.cixiongshaProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.cixiongshaProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 2
    }

    info(): string {
        return "雌雄双股剑"
    }

}

export class FangTianHuaJi extends Weapons {

    fangtianhuajiProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)

        const fangtianhuajiProxy: CardProxy<Sha> = {
            name: 'fangtianhuajishaProxy',
            shouldApply(card: Sha): boolean {
                // 当前仅当该牌是最后一张手牌杀 可以使用
                return card instanceof Sha && card.cardProperties.owner != null && card.cardProperties.owner.handCardAreas.handCardCount() == 1 && card.cardProperties.owner.handCardAreas.peekHandCard().equals(card)
            },

            apply(card: Sha): Card {
                const proxySha = new FangTianHuaJiSha(card)
                return proxySha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }

        class FangTianHuaJiSha extends ShaWrapper {

            eventWrapper: CardUsingEventWrapper<Sha>|null

            constructor(sourceCard: Sha) {
                super(sourceCard)
                this.eventWrapper = null
            }

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class FangTianHuaJiShaEvent extends CardUsingEventWrapper<Sha> {

                    /**
                     * 指定多个对象
                     */
                    moretargets: Player[]

                    /**
                     * 当前目标索引
                     */
                    currentIndex: number

                    thisCard: FangTianHuaJiSha

                    constructor(cardUsingEventHandler: CardUsingEventHandler<Sha>, thisCard: FangTianHuaJiSha) {
                        super(cardUsingEventHandler)
                        this.thisCard = thisCard
                        this.moretargets = []
                        this.currentIndex = -1
                        this.thisCard.eventWrapper = this
                    }

                    async startCardUse(): Promise<void> {
                        const sourceCard = this.card
                        const source = sourceCard.cardProperties.source
                        if (source && this.currentIndex == -1) {
                            const gm = source.gameManager
                            const maxdistance = sourceCard.specDistance(source)
                            const canPickPlayers = gm.distanceN(maxdistance)
                            gm.appendLog('您可使用方天画戟指定至多3名玩家')
                            const options = {canPickPlayers, canPickMin: 1, canPickMax: 3, currentPlayer: source}
                            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)
                            if (pickResult.cancel || pickResult.selectedPlayers.length < 1) {
                                sourceCard.cardProperties.target = null
                            } else {
                                this.moretargets = pickResult.selectedPlayers
                                this.currentIndex = 0
                                sourceCard.cardProperties.target = this.moretargets[this.currentIndex++]
                                const playernames = this.moretargets.map((t) => t.name).join(',')
                                gm.appendLog(`${source.name} 使用 ${this.thisCard.info()} 指定 ${playernames}`)
                            }
                        }

                        return super.startCardUse()
                    }

                    async afterUsing(): Promise<void> {
                        if (this.currentIndex > 0 && this.currentIndex < this.moretargets.length) {
                            const sourceCard = this.card
                            sourceCard.cardProperties.target = this.moretargets[this.currentIndex++]
                            sourceCard.cardProperties.cancelEffect = false
                            await sourceCard.use()
                        }
                        // 多个对象仍处于当前杀的结算周期内,因此要结算完成后才能继续
                        return super.afterUsing()
                    }

                }
                if (this.eventWrapper) {
                    return this.eventWrapper
                } else {
                    // 这一步故意指定target 目的是不走默认的指定玩家流程,由startCardUse 指定
                    res.card.cardProperties.target = res.player
                    return new FangTianHuaJiShaEvent(res, this)
                }
            }

            info(): string {
                return "方天画戟" + this.sourceCard.info()
            }

        }

        this.fangtianhuajiProxy = fangtianhuajiProxy

    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.fangtianhuajiProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.fangtianhuajiProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 4
    }

    info():string {
        return "方天画戟"
    }

}




export class GuDingDao extends Weapons {
    
    gudingdaoshaProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)

        const gudingdaoshaProxy: CardProxy<Sha> = {
            name: 'gudingdaoshaProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const gudingDaoShaCard = new GudingDaoSha(card)
                return gudingDaoShaCard
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }

        class GudingDaoSha extends ShaWrapper {

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class GudingDaoShaEvent extends CardUsingEventWrapper<Sha> {
                    async calHurt(): Promise<number> {
                        if (this.card.cardProperties.target && !this.card.cardProperties.target.handCardAreas.hasHandCards()) {
                            const baseHurt = await this.cardUsingEventHandler.calHurt()
                            return DefaultPromise(baseHurt + 1)
                        } else {
                            return this.cardUsingEventHandler.calHurt()
                        }
                    }
                }

                return new GudingDaoShaEvent(res)
            }

            info(): string {
                return "古锭刀" + this.sourceCard.info()
            }
        }

        this.gudingdaoshaProxy = gudingdaoshaProxy
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.gudingdaoshaProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.gudingdaoshaProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 2
    }

    info(): string {
        return "古锭刀"
    }
}


export class GuanShiFu extends Weapons {

    guanshifuProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const guanshifuProxy: CardProxy<Sha> = {
            name: 'guanshifuProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const guanShiFuSha = new GuanShiFuSha(card)
                return guanShiFuSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }

        class GuanShiFuSha extends ShaWrapper {

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class GuanShiFuShaEvent extends CardUsingEventWrapper<Sha> {
                    async afterResponse(respCard: Card[], cancel: boolean): Promise<void> {
                        const res = super.afterResponse(respCard, cancel)
                        const sourceCard = this.card
                        if (sourceCard.cardProperties.cancelEffect) {
                            const sourcePlayer = sourceCard.cardProperties.source
                            if (sourcePlayer && sourcePlayer.handCardAreas.handCardCount() >= 2) {
                                const gm = sourcePlayer.gameManager
                                gm.appendLog('您可使用贯石斧强制造成伤害,请选择弃两张牌,不使用请点取消')
                                const canPickCards = sourcePlayer.handCardAreas.handCards
                                const [canPickMin, canPickMax] = [2,2]
                                const pickPurpose = PickPurpose.DROPPING
                                const currentPlayer = sourcePlayer
                                const options = {canPickCards, canPickMin, canPickMax, pickPurpose, currentPlayer}

                                const confirmResult = await sourcePlayer.behaviorStragy.waitForPickCard(options)
                                if (!confirmResult.cancel) {
                                    const selectedCards = confirmResult.selectedCards
                                    for(const card of selectedCards) {
                                        sourcePlayer.handCardAreas.dropCard(card)
                                        card.onDrop()
                                        gm.defineDeskCard('贯石斧弃牌', card.colorCN() + card.numberCN() + card.info(), sourcePlayer.name)
                                    }
                                    sourceCard.cardProperties.cancelEffect = false
                                } else {
                                    gm.appendLog('您取消使用贯石斧,此杀不再生效')
                                }

                            }
                        }

                        return res
                    }
                }

                return new GuanShiFuShaEvent(res)
            }

            info(): string {
                return "贯石斧" + this.sourceCard.info()
            }
        }

        this.guanshifuProxy = guanshifuProxy
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.guanshifuProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.guanshifuProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 3
    }

    info(): string {
        return "贯石斧"
    }

}


export class HanBingJian extends Weapons {
    hanbingjianProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const hanbingjianProxy: CardProxy<Sha> = {
            name: 'hanbingjianProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const hanbingjianSha = new HanBingJianSha(card)
                return hanbingjianSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }

        this.hanbingjianProxy = hanbingjianProxy

        class HanBingJianSha extends ShaWrapper {

            info(): string {
                return "寒冰剑" + this.sourceCard.info()
            }

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class HanBingJianShaEvent extends CardUsingEventWrapper<Sha> {
                    async afterResponse(respCard: Card[], cancel: boolean): Promise<void> {
                        const res = super.afterResponse(respCard, cancel)
                        const sourceCard = this.card
                        const targetPlayer = sourceCard.cardProperties.target
                        const sourcePlayer = sourceCard.cardProperties.source
                        // 此杀生效,可选择弃牌让杀不生效
                        if (targetPlayer && sourcePlayer && !sourceCard.cardProperties.cancelEffect) {
                            const gm = targetPlayer.gameManager
                            const canPickMax = 2
                            if (targetPlayer.handCardAreas.hasHandCards() || targetPlayer.equipmentAreas.hasEquipment()) {
                                gm.appendLog('您可发起寒冰剑阻止伤害并丢弃其两张牌,请确认是否使用,取消则不使用,如需弃其装备牌,请先选择其装备再确认,否则默认弃手牌')
                                const options = {player: targetPlayer, canPickMin: 0, canPickMax, currentPlayer: sourcePlayer, pickRange: [Equipment]}
                                const pickResult = await sourcePlayer.behaviorStragy.waitForPickAllTypeCard(options)
                                if (!pickResult.cancel) {
                                    sourceCard.cardProperties.cancelEffect = true
                                    const selectedCards = pickResult.selectedCards
                                    let dropCount = 0
                                    for (const selectedCard of selectedCards) {
                                        if (selectedCard instanceof Equipment) {
                                            selectedCard.onDrop()
                                            dropCount++
                                        }
                                    }
                                    for(let i = canPickMax; i > dropCount; i--) {
                                        if (targetPlayer.handCardAreas.hasHandCards()) {
                                            const card = targetPlayer.handCardAreas.peekHandCard()
                                            selectedCards.push(card)
                                            targetPlayer.handCardAreas.dropCard(card)
                                            card.onDrop()
                                            gm.defineDeskCard('寒冰箭弃牌', card.colorCN() + card.numberCN() + card.info(), targetPlayer.name)
                                        }
                                    }
                                    const cardInfo = selectedCards.map((t) => t.colorCN() + t.numberCN() + t.info()).join(',')
                                    gm.appendLog(`您使用了寒冰箭丢弃了${targetPlayer.name}两张牌: ${cardInfo},本次伤害不生效`)
                                }
                            }

                        }
                        if (this.player && !sourceCard.cardProperties.cancelEffect) {
                            const gm = this.player.gameManager
                            gm.appendLog('已点取消使用寒冰箭')
                        }

                        return res
                    }
                }

                return new HanBingJianShaEvent(res)

            }
        }

        
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.hanbingjianProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.hanbingjianProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 2
    }

    info(): string {
        return "寒冰剑"
    }
}


export class QiLinGong extends Weapons {
    qilingongProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const qilingongProxy: CardProxy<Sha> = {
            name: 'qilingongProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const qilingongSha = new QiLinGongSha(card)
                return qilingongSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }

        this.qilingongProxy = qilingongProxy
        class QiLinGongSha extends ShaWrapper {

            info(): string {
                return "麒麟弓" + this.sourceCard.info()
            }

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class QiLinGongShaEvent extends CardUsingEventWrapper<Sha> {
                    async afterResponse(respCard: Card[], cancel: boolean): Promise<void> {
                        const res = super.afterResponse(respCard, cancel)
                        const sourceCard = this.card
                        const targetPlayer = sourceCard.cardProperties.target
                        const sourcePlayer = sourceCard.cardProperties.source
                        
                        if (sourcePlayer && targetPlayer && !sourceCard.cardProperties.cancelEffect) {
                            const equipmentArea = targetPlayer.equipmentAreas
                            const gm = targetPlayer.gameManager
                            const canPickMax = 1
                            // 判断有马装备区
                            if (equipmentArea.hasMinusOneHourse() || equipmentArea.hasPlusOneHourse()) {
                                gm.appendLog('您可发起麒麟弓弃马,请确认是否使用,取消则不使用,请先选择其装备再确认')
                                const options = {player: targetPlayer, canPickMin: 0, canPickMax, currentPlayer: sourcePlayer, pickRange: [PlusOneHourse, MinusOneHourse]}
                                const pickResult = await sourcePlayer.behaviorStragy.waitForPickAllTypeCard(options)
                                if (!pickResult.cancel && pickResult.selectedCards.length > 0) {
                                    const selectedEquipment = pickResult.selectedCards[0]
                                    if (selectedEquipment instanceof Equipment) {
                                        selectedEquipment.onDrop()
                                        const cardInfo = selectedEquipment.colorCN() + selectedEquipment.numberCN() + selectedEquipment.info()
                                        gm.appendLog('您使用麒麟弓丢弃其 ' + cardInfo)
                                    }
                                } else {
                                    gm.appendLog('您取消使用麒麟弓')
                                }
                            }

                        }
                        return res
                    }
                }

                return new QiLinGongShaEvent(res)
            }
        }
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.qilingongProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.qilingongProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 5
    }

    info(): string {
        return "麒麟弓"
    }
}

/**
 * 青钢剑
 */
export class QingGangJian extends Weapons {
    qinggangjianProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const qinggangjianProxy: CardProxy<Sha> = {
            name: 'qilingongProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const qinggangjianSha = new QingGangJianSha(card)
                return qinggangjianSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }
        this.qinggangjianProxy = qinggangjianProxy

        class QingGangJianSha extends ShaWrapper {

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)
                class QingGangJianShaEvent extends CardUsingEventWrapper<Sha> {
                    targetShield: Shield|null = null

                    async startCardUse(): Promise<void> {
                        const res = this.cardUsingEventHandler.startCardUse()
                        const sourceCard = this.card
                        const targetPlayer = sourceCard.cardProperties.target
                        if (targetPlayer) {
                            const equipment = targetPlayer.equipmentAreas.getShield()
                            if (equipment) {
                                this.targetShield = equipment
                                targetPlayer.equipmentAreas.onDrop(equipment)
                            }
                        }
                        return res
                    }

                    async afterUsing(): Promise<void> {
                        const sourceCard = this.card
                        const targetPlayer = sourceCard.cardProperties.target
                        const res = this.cardUsingEventHandler.afterUsing()
                        if (targetPlayer && this.targetShield) {
                            targetPlayer.equipmentAreas.equip(this.targetShield)
                        }
                        return res
                    }
                }
                return new QingGangJianShaEvent(res)
            }

            info(): string {
                return "青钢剑" + this.sourceCard.info()
            }
        }
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.qinggangjianProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.qinggangjianProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 2
    }

    info(): string {
        return "青釭剑"
    }
}

export class QingLongYanYueDao extends Weapons {
    qionglongyanyuedaoProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const qionglongyanyuedaoProxy: CardProxy<Sha> = {
            name: 'qilingongProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const qingLongYanYueDaoSha = new QingLongYanYueDaoSha(card)
                return qingLongYanYueDaoSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }
        this.qionglongyanyuedaoProxy = qionglongyanyuedaoProxy

        class QingLongYanYueDaoSha extends ShaWrapper {

            info(): string {
                return "青龙偃月刀" + this.sourceCard.info()
            }

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class QingLongYanYueDaoShaEvent extends CardUsingEventWrapper<Sha> {
                    nextSelectedSha: Sha| null = null

                    async afterResponse(respCard: Card[], cancel: boolean): Promise<void> {
                        const res = super.afterResponse(respCard, cancel)
                        const sourceCard = this.card
                        const sourcePlayer = sourceCard.cardProperties.source
                        const targetPlayer = sourceCard.cardProperties.target
                        if (sourceCard && sourcePlayer && targetPlayer && sourceCard.cardProperties.cancelEffect) {
                            const gm = sourcePlayer.gameManager
                            const shaCards = sourcePlayer.handCardAreas.matchesHandCards(Sha)
                            if (shaCards.length > 0) {
                                gm.appendLog('您可发起青龙偃月刀继续追杀,请确认是否使用,取消则不使用,请先选择一张杀再确认')
                                // TODO 不再控制杀次数限制
                                const canPickCards = shaCards
                                const [canPickMin, canPickMax] = [1,1]
                                const pickPurpose = PickPurpose.USING
                                const currentPlayer = sourcePlayer
                                const options = {canPickCards, canPickMin, canPickMax, pickPurpose, currentPlayer}
                                const pickResult = await sourcePlayer.behaviorStragy.waitForPickCard(options)
                                if (!pickResult.cancel && pickResult.selectedCards.length > 0) {
                                    const selectedCard = pickResult.selectedCards[0]
                                    if (selectedCard instanceof Sha) {
                                        selectedCard.cardProperties.target = targetPlayer
                                        this.nextSelectedSha = selectedCard
                                    }
                                } else {
                                    gm.appendLog('您取消发起青龙偃月刀')
                                }
                            }
                        }
                        return res
                    }

                    async afterUsing(): Promise<void> {
                        // 需要将当前杀结算完成后 再进行下一张杀的使用
                        const sourceCard = this.card
                        const sourcePlayer = sourceCard.cardProperties.source
                        const res = super.afterUsing()
                        if (sourceCard && sourcePlayer && this.nextSelectedSha) {
                            const selectedCard = sourcePlayer.handCardAreas.useCard(this.nextSelectedSha)
                            await selectedCard.use()
                        }
                        return res
                    }
                }
                return new QingLongYanYueDaoShaEvent(res)
            }
        }
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.qionglongyanyuedaoProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.qionglongyanyuedaoProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 3
    }

    info(): string {
        return "青龙偃月刀"
    }
}

export class SanJianLiangRenDao extends Weapons {
    sanjianliangrendaoProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const sanjianliangrendaoProxy: CardProxy<Sha> = {
            name: 'sanjianliangrendaoProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const sanJianLiangRenDaoSha = new SanJianLiangRenDaoSha(card)
                return sanJianLiangRenDaoSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }
        this.sanjianliangrendaoProxy = sanjianliangrendaoProxy

        class SanJianLiangRenDaoSha extends ShaWrapper {

            info(): string {
                return "三尖两刃刀" + this.sourceCard.info()
            }

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)

                class SanJianLiangRenDaoShaEvent extends CardUsingEventWrapper<Sha> {
                    nextSelectedSha: Sha| null = null

                    async afterSettle(): Promise<void> {
                        const res = super.afterSettle()
                        const sourceCard = this.card
                        const sourcePlayer = sourceCard.cardProperties.source
                        const targetPlayer = sourceCard.cardProperties.target
                        if (sourceCard && sourcePlayer && targetPlayer && !sourceCard.cardProperties.cancelEffect) {
                            const gm = targetPlayer.gameManager
                            const weapon =sourcePlayer.equipmentAreas.getWeapon()
                            const targetNearby = gm.playerDistanceN(targetPlayer, 1)
                            const sourceHandCards = sourcePlayer.handCardAreas.handCards
                            if (weapon && weapon instanceof SanJianLiangRenDao && targetNearby.length > 0 && sourceHandCards.length > 0) {
                                gm.appendLog('您可使用三尖两刃刀弃置一张牌对其附近人造成伤害,请选择需要弃之的牌,取消则放弃使用')
                                const canPickCards = sourceHandCards
                                const [canPickMin, canPickMax] = [1,1]
                                const pickPurpose = PickPurpose.DROPPING
                                const currentPlayer = sourcePlayer
                                const options = {canPickCards, canPickMin, canPickMax, pickPurpose, currentPlayer}

                                const dropCardResult = await sourcePlayer.behaviorStragy.waitForPickCard(options)
                                let pickPlayerResult = createDefaultEvent({cancel: true})
                                if (!dropCardResult.cancel) {
                                    gm.appendLog('您可使用三尖两刃刀弃置一张牌对其附近人造成伤害,请选择需要造成伤害的玩家(可选自己),取消则放弃使用')
                                    const options = {canPickPlayers: targetNearby, canPickMin: 1, canPickMax: 1, currentPlayer: sourcePlayer}
                                    pickPlayerResult = await sourcePlayer.behaviorStragy.waitForPickPlayer(options)
                                }

                                if (!dropCardResult.cancel && dropCardResult.selectedCards.length == 1 && !pickPlayerResult.cancel && pickPlayerResult.selectedPlayers.length == 1) {
                                    const dropCard = dropCardResult.selectedCards[0]
                                    sourcePlayer.handCardAreas.dropCard(dropCard)
                                    dropCard.onDrop()
                                    gm.defineDeskCard('三尖两刃刀弃牌', dropCard.colorCN() + dropCard.numberCN() + dropCard.info(), sourcePlayer.name)

                                    const selectedPlayer = pickPlayerResult.selectedPlayers[0]
                                    const targetHandler = selectedPlayer.createCardUsingEventHandler(weapon.defaultHurtHandler(selectedPlayer))
                                    const hurtCount = await targetHandler.calHurt()
                                    await targetHandler.settleHurt(hurtCount)
                                    gm.appendLog('您使用三尖两刃刀对' + selectedPlayer.name + '造成' + hurtCount + '伤害')
                                    await targetHandler.playerBeingDead()
                                    await targetHandler.afterSettle()
                                    await targetHandler.afterUsing()
                                } else {
                                    gm.appendLog('您取消使用三尖两刃刀')
                                }
                            }

                        }
                        return res
                    }
                }
                return new SanJianLiangRenDaoShaEvent(res)
            }

        }
    }

    defaultHurtHandler(target: Player): CardUsingEventHandler<SanJianLiangRenDao> {
        class SanJianLiangRenDaoDefaultHandler extends EmptyCardUsingEventHandler<SanJianLiangRenDao> {
            calHurt(): Promise<number> {
                return DefaultPromise(1)
            }

            settleHurt(n: number): Promise<void>  {
                if (this.player) {
                    this.player.reduceHP(n)
                }

                return super.settleHurt(n)
            }
        }
        this.cardProperties.target = target
        return new SanJianLiangRenDaoDefaultHandler(this, target)
    }

    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.sanjianliangrendaoProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.sanjianliangrendaoProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 3
    }

    info(): string {
        return "三尖两刃刀"
    }
}


export class ZhuGeLianLu extends Weapons {
    zhuGeLianLuShaProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const zhuGeLianLuShaProxy :CardProxy<Sha> = {
            name: 'zhuGeLianLuShaProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const zhuGeLianLuSha = new ZhuGeLianLuSha(card)
                return zhuGeLianLuSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }
        this.zhuGeLianLuShaProxy = zhuGeLianLuShaProxy
        class ZhuGeLianLuSha extends ShaWrapper {

            canuse(): boolean {
                if (!this.cardProperties.owner) {
                    return false
                }
                // 使用 诸葛连弩 的杀没有次数限制
                return this.canPickPlayer()
            }

            info(): string {
                return "诸葛连弩" + this.sourceCard.info()
            }

            
        }
    }

    async use(): Promise<void> {
        const res = super.use()
        const owner = this.cardProperties.owner
        if (owner) {
            owner.handCardAreas.registerCardProxy(this.zhuGeLianLuShaProxy)
        }

        return res
    }

    onDrop(): void {
        const owner = this.cardProperties.owner
        if (owner && this.hasEquip()) {
            owner.handCardAreas.removeCardProxy(this.zhuGeLianLuShaProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 1
    }

    info(): string {
        return "诸葛连弩"
    }
}


export class ZhuQueYuShan extends Weapons {
    zhuqueyushaProxy: CardProxy<Sha>

    constructor(color: Color, number: number) {
        super(color, number)
        const zhuqueyushaProxy :CardProxy<Sha> = {
            name: 'zhuqueyushaProxy',
            shouldApply(card: Sha): boolean {
                return card instanceof Sha
            },

            apply(card: Sha): Card {
                const zhuqueyushanSha = new ZhuQueYuShanSha(card)
                return zhuqueyushanSha
            },

            equals(obj: CardProxy<Sha>) {
                return this.name == obj.name
            },

            expirePhase() {
                return PhaseEnum.OVER
            }
        }
        this.zhuqueyushaProxy = zhuqueyushaProxy
        class ZhuQueYuShanSha extends ShaWrapper {

            constructor(sourceCard: Sha) {
                super(sourceCard)
                this.shaHurtType = sourceCard.shaHurtType == HurtType.NORMAL ? HurtType.FIRE : sourceCard.shaHurtType
            }

            info(): string {
                return "朱雀羽扇" + super.info() + this.sourceCard.info()
            }

            createCardUsingEventHandler(card: Sha, player: Player | null): CardUsingEventHandler<Sha> {
                const res = this.sourceCard.createCardUsingEventHandler(card, player)
                return res
            }

            hurtType(): HurtType {
                return this.shaHurtType
            }
        }
    }

    
    async use(): Promise<void> {
        const res = super.use()
        if (this.cardProperties.owner && this.hasEquip()) {
            this.cardProperties.owner.handCardAreas.registerCardProxy(this.zhuqueyushaProxy)
        }

        return res
    }

    onDrop(): void {
        if (this.cardProperties.owner) {
            this.cardProperties.owner.handCardAreas.removeCardProxy(this.zhuqueyushaProxy)
        }
        super.onDrop()
    }

    attackDistance():number {
        return 4
    }

    info(): string {
        return "朱雀羽扇"
    }
}
